home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / windownt / wvnsrc75.zip / WVART.C < prev    next >
C/C++ Source or Header  |  1993-02-03  |  13KB  |  487 lines

  1. /*---  wvart.c ------------------------------------------- */
  2. /*  This file contains the window procedure for the Article Viewing window
  3.  *  for WinVn.
  4.  */
  5.  
  6. #include "windows.h"
  7. #ifndef MAC
  8. #include "winundoc.h"
  9. #endif
  10. #include "WVglob.h"
  11. #include "WinVn.h"
  12.  
  13. long find_article_by_subject (TypHeader far *headers,long artindex,long num_headers);
  14. int cursor_to_char_number (int X, int Y,TypDoc *DocPtr,TypBlock far **BlockPtr,TypLine far **LinePtr);
  15. void view_article_by_message_id (TypDoc *Doc, char far *article_request, long artindex);
  16.  
  17. long
  18. find_article_by_subject (TypHeader far *headers,
  19.                 long artindex,
  20.                 long num_headers)
  21. {
  22. char far *subject = headers[artindex++].subject;
  23.  
  24.     do {
  25.         if (lstrcmpi (headers[artindex].subject, subject) == 0)
  26.         return (artindex);        /* return the index */
  27.     } while (artindex++ < num_headers);
  28.  
  29.     return (-1);            /* not found */
  30. }
  31.  
  32. /****************************************************************************
  33.  
  34.     FUNCTION: WinVnArtWndProc(HWND, unsigned, WORD, LONG)
  35.  
  36.     PURPOSE:  Processes messages
  37.  
  38. ****************************************************************************/
  39.  
  40. long FAR PASCAL 
  41. WinVnArtWndProc (hWnd, message, wParam, lParam)
  42.      HWND hWnd;
  43.      unsigned message;
  44.      WPARAM wParam;
  45.      LPARAM lParam;
  46. {
  47.   FARPROC lpProcAbout;
  48.   HMENU hMenu;
  49.  
  50.   PAINTSTRUCT ps;        /* paint structure          */
  51.  
  52.   HDC hDC;            /* handle to display context */
  53.   RECT myRect;            /* selection rectangle      */
  54.   HWND hWndView;
  55.   HDC hDCView;
  56.   TypDoc *ThisDoc;
  57.   TypGroup far *GroupDoc;
  58.   int ih, j;
  59.   int found, X, Y, charnum;
  60.   int imemo;
  61.   int CtrlState;
  62.   TypLine far *LinePtr, far * ArtLinePtr;
  63.   TypBlock far *BlockPtr, far * ArtBlockPtr;
  64.   HANDLE hBlock;
  65.   char mybuf[MAXINTERNALLINE];
  66.   unsigned int Offset;
  67.   int reply;
  68.   int result;
  69.   char far *cptr;
  70.   char far *textptr;
  71.   int textlen;
  72.   TypLineID MyLineID;
  73.   HANDLE header_handle;
  74.   TypHeader * headers;
  75.   long header_num;
  76.  
  77. #ifdef MAC
  78.   int vRef;
  79. #endif
  80.  
  81.   for (ih = 0, found = FALSE; !found && ih < MAXARTICLEWNDS; ih++)
  82.     {
  83.       if (ArticleDocs[ih].hDocWnd == hWnd)
  84.     {
  85.       found = TRUE;
  86.       ThisDoc = &(ArticleDocs[ih]);
  87.     }
  88.     }
  89.  
  90.   if (!found)
  91.     {
  92.       ThisDoc = CommDoc;
  93.     }
  94.  
  95.  
  96.   switch (message)
  97.     {
  98.  
  99.     case WM_ACTIVATE:
  100.     case WM_SETFOCUS:
  101.       if (wParam)
  102.     {
  103.       ActiveArticleDoc = ThisDoc;
  104.     }
  105.       /* fall through */
  106.     case WM_SYSCOMMAND:
  107.       return (DefWindowProc (hWnd, message, wParam, lParam));
  108.  
  109.     case WM_SIZE:
  110.       GetClientRect (hWnd, &myRect);
  111.       ThisDoc->ScXWidth = myRect.right;
  112.       ThisDoc->ScYHeight = myRect.bottom;
  113.       ThisDoc->ScYLines = (myRect.bottom - myRect.top - TopSpace) / ArtLineHeight;
  114.       ThisDoc->ScXChars = (myRect.right - myRect.left - SideSpace) / ArtCharWidth;
  115.       break;
  116.  
  117.  
  118.     case WM_DESTROY:
  119.       ThisDoc->InUse = FALSE;
  120.       if (ThisDoc == CommDoc)
  121.     {
  122.       CommBusy = FALSE;
  123.       CommDoc = (TypDoc *) NULL;
  124.     }
  125.       /* Clear the pointer in the line for this article in the   */
  126.       /* group  document.  This pointer currently points       */
  127.       /* to the current document, which we are wiping out      */
  128.       /* with the destruction of this window.                  */
  129.  
  130.       if (ThisDoc->ParentDoc)
  131.     {
  132.            LockLine (ThisDoc->ParentDoc->hParentBlock,
  133.                      ThisDoc->ParentDoc->ParentOffset,
  134.                      ThisDoc->ParentDoc->ParentLineID,
  135.                      &BlockPtr, &LinePtr);
  136.  
  137.     GroupDoc = (TypGroup far *) ((char far *) LinePtr + sizeof (TypLine));
  138.  
  139.     header_handle = GroupDoc->header_handle;
  140.     headers = (TypHeader *) ((char *) GlobalLock (header_handle) + sizeof(char *)) ;
  141.  
  142.     headers[ThisDoc->LastSeenLineID].ArtDoc = (TypDoc *) NULL;
  143.     UnlockLine (BlockPtr, LinePtr, &hBlock, &Offset, &MyLineID);
  144.     GlobalUnlock (header_handle);
  145.     }
  146.       /* Clear document                                        */
  147.       FreeDoc (ThisDoc);
  148.  
  149.       /* If there's another article window, make it the active   */
  150.       /* artcile window so we don't create a new one if the      */
  151.       /* New Article flag is FALSE.                              */
  152.  
  153.       for (j = MAXARTICLEWNDS - 1; j >= 0; j--)
  154.     {
  155.       if (ArticleDocs[j].InUse)
  156.         {
  157.           ActiveArticleDoc = &(ArticleDocs[j]);
  158.           break;
  159.         }
  160.     }
  161.       break;
  162.  
  163.     case WM_KEYDOWN:
  164.       /* See if this key should be mapped to a scrolling event
  165.        * for which we have programmed the mouse.  If so,
  166.        * construct the appropriate mouse call and call the mouse code.
  167.        */
  168. #ifndef MAC
  169.       if (wParam == VK_F6)
  170.     {
  171.       NextWindow (ThisDoc);
  172.     }
  173.       else
  174.     {
  175.       CtrlState = GetKeyState (VK_CONTROL) < 0;
  176.       for (j = 0; j < NUMKEYS; j++)
  177.         {
  178.           if (wParam == key2scroll[j].wVirtKey &&
  179.           CtrlState == key2scroll[j].CtlState)
  180.         {
  181.           SendMessage (hWnd, key2scroll[j].iMessage,
  182.                    key2scroll[j].wRequest, 0L);
  183.           break;
  184.         }
  185.         }
  186.     }
  187. #endif
  188.       break;
  189.  
  190.     case WM_LBUTTONDBLCLK:
  191.       X = LOWORD (lParam);
  192.       Y = HIWORD (lParam);
  193.  
  194.       charnum = cursor_to_char_number (X,Y,ThisDoc,&BlockPtr,&LinePtr);
  195.  
  196.       if (charnum >= 0) {
  197.         textlen = ((TypText far *) ((char far *) LinePtr +
  198.                                 sizeof (TypLine)))->NameLen;
  199.  
  200.         textptr = (char far *) ((char far *) LinePtr +
  201.                                sizeof (TypLine) + sizeof (TypText) );
  202.  
  203.         if (textlen)
  204.         {                    /* find a message-id */
  205.           char far *start, far *end;
  206.  
  207.           for (start = textptr + charnum; start >= textptr; start--) 
  208.             if (*start == '<') break;
  209.  
  210.           for (end = textptr + charnum; end < (textptr + textlen); end++) 
  211.             if (*end == '>') break;
  212.  
  213.           if ((start >= textptr) && (end < (textptr + textlen))) {
  214.             sprintf (str, "ARTICLE %.*Fs\r", (int) ((long) end - (long) start + 1), start);
  215.             LockLine (ThisDoc->ParentDoc->hParentBlock,
  216.                            ThisDoc->ParentDoc->ParentOffset,
  217.                    ThisDoc->ParentDoc->ParentLineID,
  218.                    &BlockPtr, &LinePtr);
  219.             GroupDoc = (TypGroup far *) ((char far *) LinePtr + sizeof (TypLine));
  220.             view_article_by_message_id (ThisDoc->ParentDoc, str, ThisDoc->LastSeenLineID);
  221.           }
  222.         }
  223.       }
  224.  
  225.       break;
  226.  
  227.     case WM_VSCROLL:
  228.       ScrollIt (ThisDoc, wParam, lParam);
  229.       break;
  230.  
  231.     case WM_PAINT:
  232.       {
  233.     HANDLE hBlock;
  234.     unsigned int Offset, MyLen, width;
  235.     int VertLines, HorzChars;
  236.     int EndofDoc = FALSE;
  237.     int RangeHigh, CurPos;
  238.     int RestX;
  239.     char far *textptr;
  240.     TypArticle far *MyArt;
  241.     TypBlock far *BlockPtr;
  242.     TypLine far *LinePtr;
  243.     HANDLE hBlackBrush;
  244.     DWORD MyColors[4], MyBack[4];
  245.     int MyColorMask = 1, PrevColorMask = MyColorMask;
  246.     SIZE string_size;
  247. #ifdef MAC
  248.     RECT myRect;
  249.     POINT myPoint;
  250. #endif
  251.  
  252.     hDC = BeginPaint (hWnd, &ps);
  253.  
  254.     GetClientRect (hWnd, &myRect);
  255.     SelectObject (hDC, hFontArt);
  256.     VertLines = ThisDoc->ScYLines;
  257.     HorzChars = ThisDoc->ScXChars;
  258.  
  259.     LockLine (ThisDoc->hCurTopScBlock, ThisDoc->TopScOffset, ThisDoc->TopScLineID,
  260.           &BlockPtr, &LinePtr);
  261.  
  262.     /* Update the scroll bar thumb position.                 */
  263.  
  264.     CurPos = ThisDoc->TopLineOrd;
  265.     if (CurPos < 0)
  266.       CurPos = 0;
  267.     RangeHigh = ThisDoc->TotalLines - VertLines;
  268.     if (RangeHigh < 0)
  269.       RangeHigh = 0;
  270.     SetScrollRange (hWnd, SB_VERT, 0, RangeHigh, FALSE);
  271.     SetScrollPos (hWnd, SB_VERT, CurPos, TRUE);
  272. #ifdef MAC
  273.     myRect.right = ThisDoc->DocClipRect.right;
  274.     myRect.top = 0;
  275.     myRect.bottom = ArtLineHeight;
  276. #endif
  277.     /* Now paint this stuff on the screen for debugging. */
  278.  
  279.     X = SideSpace;
  280.     Y = StartPen;
  281.  
  282.     if (LinePtr->length != END_OF_BLOCK)
  283.       do
  284.         {
  285.           MyLen = LinePtr->length - sizeof (TypLine) - sizeof (int) - 1;
  286.           MyLen = ((TypText far *) ((char far *) LinePtr +
  287.                     sizeof (TypLine)))->NameLen;
  288.           textptr = (char far *) LinePtr + sizeof (TypLine) + sizeof (TypText);
  289.  
  290.           /* Now write out the line.                            */
  291.  
  292. #if 1
  293.           GetTextExtentPoint (hDC, textptr, MyLen, &string_size);
  294.  
  295.           width = string_size.cx;
  296. #else
  297.           width = ArtCharWidth * MyLen;
  298. #endif
  299.           TextOut (hDC, X, Y, textptr, MyLen);
  300. #ifdef MAC
  301.           GetPen (&myPoint);
  302.           myRect.left = myPoint.h;
  303.           FillRect (&myRect, white);
  304.  
  305.           myRect.top += ArtLineHeight;
  306.           myRect.bottom += ArtLineHeight;
  307. #else
  308.           RestX = X + width;
  309.           PatBlt (hDC, RestX, Y, myRect.right - RestX, ArtLineHeight, PATCOPY);
  310. #endif
  311. #if 0
  312.           if (MyLen < HorzChars)
  313.         {
  314.           RestX = X + width;
  315. #if 0
  316.           TextOut (hDC, RestX, Y, Blanks, MAXINTERNALLINE);
  317. #endif
  318.           PatBlt (hDC, RestX, Y, myRect.right - RestX, ArtLineHeight, PATCOPY);
  319.         }
  320. #endif
  321.           Y += ArtLineHeight;
  322.         }
  323.       while (--VertLines > 0 && NextLine (&BlockPtr, &LinePtr));
  324.  
  325.     /* We've reached the end of the data to be displayed     */
  326.     /* on this window.  If there's more screen real estate   */
  327.     /* left, just blank it out.                              */
  328.  
  329. #if !MAC
  330.     PatBlt (hDC, 0, Y, myRect.right, myRect.bottom - Y, PATCOPY);
  331. #else
  332.     /* myRect.top = myRect.top + ArtLineHeight; */
  333.     myRect.bottom = ThisDoc->DocClipRect.bottom;
  334.     myRect.left = 0;
  335.     EraseRect (&myRect);
  336. #endif
  337. #if 0
  338.     while (VertLines-- > -1)
  339.       {
  340.         TextOut (hDC, X, Y, Blanks, HorzChars);
  341.         Y += ArtLineHeight;
  342.       }
  343. #endif
  344.  
  345.     UnlockLine (BlockPtr, LinePtr, &hBlock, &Offset, &MyLineID);
  346.     EndPaint (hWnd, &ps);
  347.     break;
  348.       }
  349.  
  350.     case WM_COMMAND:
  351.       switch (wParam)
  352.     {
  353.  
  354.     case IDM_EXIT:
  355.       DestroyWindow (hWnd);
  356.       break;
  357.  
  358.     case IDM_SAVE:
  359.       if (strcmp (SaveArtFileName, ""))
  360.         {
  361.           SaveArtAppend = TRUE;
  362.           MRRWriteDocument (ActiveArticleDoc, sizeof (TypText), SaveArtFileName, SaveArtvRef, SaveArtAppend);
  363.           /* Should the 0 be sizeof(TypText) ? */
  364.           break;
  365.         }
  366.       else
  367.         {
  368.           goto saveas;
  369.         }
  370.  
  371.     case IDM_SAVEAS:
  372.     saveas:;
  373. #ifndef MAC
  374.       if (DialogBox (hInst, "WinVnSaveArt", hWnd, lpfnWinVnSaveArtDlg))
  375.         {
  376.           InvalidateRect (hWnd, NULL, TRUE);
  377.         }
  378. #else
  379.       result = MySaveAs (SaveArtFileName, &SaveArtvRef, &SaveArtAppend);
  380.       if (result)
  381.         {
  382.           MRRWriteDocument (ActiveArticleDoc, sizeof (TypText), SaveArtFileName, SaveArtvRef, SaveArtAppend);
  383.         }
  384. #endif
  385.       break;
  386.  
  387.     case IDM_FIND_NEXT_SAME:
  388.     case IDM_NEXT_ARTICLE:
  389.  
  390.         if (ThisDoc->ParentDoc)
  391.         {
  392.             LockLine (ThisDoc->ParentDoc->hParentBlock,
  393.                       ThisDoc->ParentDoc->ParentOffset,
  394.                       ThisDoc->ParentDoc->ParentLineID,
  395.                       &BlockPtr, &LinePtr);
  396.  
  397.             GroupDoc = (TypGroup far *) ((char far *) LinePtr + sizeof (TypLine));
  398.  
  399.             if (wParam == IDM_FIND_NEXT_SAME) {
  400.                 header_handle = GroupDoc->header_handle;
  401.                 headers = (TypHeader far *) ((char *)GlobalLock (header_handle) + sizeof(char *)) ;
  402.  
  403.                 header_num = find_article_by_subject (headers,ThisDoc->LastSeenLineID,GroupDoc->total_headers - 1);
  404.  
  405.                 GlobalUnlock (header_handle);
  406.                 if (header_num >= 0)
  407.                 ViewArticle (ThisDoc->ParentDoc, header_num, TRUE);
  408.                 else MessageBox (hWnd, "No more articles", "That's all!", MB_OK); 
  409.             }
  410.  
  411.             else {
  412.  
  413.                 if (GroupDoc)
  414.                 {
  415.                   if (ThisDoc->LastSeenLineID < (GroupDoc->total_headers - 1) )
  416.                     ViewArticle (ThisDoc->ParentDoc, ThisDoc->LastSeenLineID + 1, TRUE);
  417.                   else MessageBox (hWnd, "No more articles", "That's all!", MB_OK);
  418.                 }
  419.                 else MessageBox (hWnd, "Sorry--you must have the group window around\n\for me to be able to find the next article", "Can't find next article", MB_OK);
  420.             UnlockLine (BlockPtr, LinePtr, &hBlock, &Offset, &MyLineID);
  421.             }
  422.         }
  423.         else MessageBox (hWnd, "That Group's window is gone.  Reopen it.", "Error", MB_OK);
  424.  
  425.           break;
  426.  
  427.     case IDM_FOLLOWUP:
  428.       CreatePostingWnd (ThisDoc, DOCTYPE_POSTING);
  429.       break;
  430.  
  431.     case IDM_MAIL:
  432.       CreatePostingWnd (ThisDoc, DOCTYPE_MAIL);
  433.       break;
  434.  
  435.     case IDM_SEARCH:
  436.  
  437.       FindDoc = ThisDoc;
  438.  
  439.       if (DialogBox (hInst, "WinVnFind", hWnd, lpfnWinVnFindDlg))
  440.         {
  441.           found = DoFind (TRUE);
  442.           if (!found)
  443.         {
  444.           strcpy (mybuf, "\"");
  445.           strcat (mybuf, FindDoc->SearchStr);
  446.           strcat (mybuf, "\" not found.");
  447.           MessageBox (hWnd, mybuf, "Not found", MB_OK);
  448.         }
  449.         }
  450.  
  451.       break;
  452.  
  453.     case IDM_SEARCH_NEXT:
  454.  
  455.       FindDoc = ThisDoc;
  456.       if (strcmp (FindDoc->SearchStr, ""))
  457.         {
  458.           found = DoFind (FALSE);
  459.           if (!found)
  460.         {
  461.           strcpy (mybuf, "\"");
  462.           strcat (mybuf, FindDoc->SearchStr);
  463.           strcat (mybuf, "\" not found.");
  464.           MessageBox (hWnd, mybuf, "No more occurrences", MB_OK);
  465.         }
  466.         }
  467.       break;
  468.  
  469.     }
  470.  
  471.     break;
  472.  
  473.     default:
  474.       return (DefWindowProc (hWnd, message, wParam, lParam));
  475.     }
  476.   return (0);
  477. }
  478.  
  479.  
  480.  
  481.  
  482.  
  483.  
  484.  
  485.  
  486.  
  487.